home *** CD-ROM | disk | FTP | other *** search
- Subject: v24i088: Simple load-balancing program
- Newsgroups: comp.sources.unix
- Approved: rsalz@uunet.UU.NET
- X-Checksum-Snefru: 857df0d3 76ae7246 72b0351d a8f66778
-
- Submitted-by: Dikran Kassabian <deke@ee.rochester.edu>
- Posting-number: Volume 24, Issue 88
- Archive-name: lb
-
-
- LB is a load-balancing program. It can check the current load on various
- machines on a LAN, and find the best candidate machine to accept a new job
- to it's run queue. Additionally, it can send the job to that machine
- using rsh(1).
-
- LB works best in homogeneous environments, where each machine has similar
- or identical file system layout. Here at the University of Rochester
- Department of Electrical Engineering, we have nearly 70 SUN computers,
- which share home-directories and local binaries. When a user sitting at a
- small workstation wants to run a compute intensive job, LB helps to find a
- machine on the network that has a low load, knowing that that machine will
- also have his/her home directory and required program.
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then feed it
- # into a shell via "sh file" or similar. To overwrite existing files,
- # type "sh file -c".
- # The tool that generated this appeared in the comp.sources.unix newsgroup;
- # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
- # Contents: INSTALL Makefile OTHER_SERVERS README config.h lb.1 lb.5
- # rsdclnt.c srvclnt.c st_sendrecv.c stats.h
- # Wrapped by rsalz@litchi.bbn.com on Thu Jun 6 12:43:40 1991
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- echo If this archive is complete, you will see the following message:
- echo ' "shar: End of archive."'
- if test -f 'INSTALL' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'INSTALL'\"
- else
- echo shar: Extracting \"'INSTALL'\" \(1988 characters\)
- sed "s/^X//" >'INSTALL' <<'END_OF_FILE'
- X
- X LB - The Load Balancer (version 1.2)
- X by Dikran Kassabian
- X
- X University Of Rochester
- X Department of Electrical Engineering
- X March 3, 1991
- X
- XINSTALLATION NOTES:
- X
- X
- X1. CHOOSING A SERVER
- X====================
- XThe lb load balancer uses statistics gathered via connection with
- Xservers on each of the candidate machines. Two servers are supported,
- Xthe SUN rstatd, and Dave Curry's statsrv. The installer must see to
- Xit that all candidate machines support the selected server program.
- XIn an all SUN environment, rstatd is the better choice as it seems to
- Xbe somewhat faster. In other environments, it may be necessary to use
- Xthe statsrv server, which is public domain.
- X
- X2. BUILDING THE PROGRAM
- X=======================
- XOnce a server is selected, the Makefile must be edited to reflect the
- Xchoice. If rstatd is to be used, edit the Makefile definition for SERVER
- Xto be 'SERVER=rstatd'. If the statsrv server is to be used, make it
- X'SERVER=statsrv'. Check the defines in config.h, and choose the location
- Xof the configuration file. Remember that every machine that wants to
- Xuse lb needs to be able to see that configuration file. You may choose
- Xto use multiple copies, or a single copy that all machines can see. Once
- Xthe Makefile and config.h are setup to your satisfaction, type 'make'.
- XThe program 'lb' will be built.
- X
- X3. WRITING THE CONFIGURATION FILE
- X=================================
- XThe configuration file contains information on every machine on which lb
- Xmay start jobs. See the man page lb(5) for details on its setup.
- X
- X
- X4. INSTALLING THE FILES
- X=======================
- XInstall the program lb in a location within the path of the users requiring
- Xit. Good choices would include /usr/local/bin or /usr/new. Then install
- Xthe configuration file wherever the config.h file claimed it would be. Again,
- Xremember that every machine needs to have read access to this file. Finally,
- Xinstall the man pages lb(1) and lb(5) as appropriate.
- X
- XThat's all!
- X
- X
- XDeke Kassabian, 3/8/91
- END_OF_FILE
- if test 1988 -ne `wc -c <'INSTALL'`; then
- echo shar: \"'INSTALL'\" unpacked with wrong size!
- fi
- # end of 'INSTALL'
- fi
- if test -f 'Makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Makefile'\"
- else
- echo shar: Extracting \"'Makefile'\" \(1069 characters\)
- sed "s/^X//" >'Makefile' <<'END_OF_FILE'
- X#
- X# Makefile for "lb", the load-balancer
- X# ^Deke Kassabian 6/3/88, mods and additions 3/7/89
- X#
- XSERVER=rstatd
- X#
- X#CFLAGS= -g -f68881
- XCFLAGS= -O
- XLDFLAGS= -s
- X#PRINT= ptroff -man
- XPRINT= troff -t -man
- X
- XSRCS= rsdclnt.c srvclnt.c st_sendrecv.c stats.h config.h
- XMANS= lb.1 lb.5
- XOBJS_SRV= srvclnt.o st_sendrecv.o
- XOBJS_RSD= rsdclnt.o
- XLIBS= -lrpcsvc
- X
- Xlb: lb.$(SERVER)
- X @echo "lb has been built for $(SERVER) server."
- X
- Xlb.rstatd: $(OBJS_RSD)
- X $(CC) $(CFLAGS) $(LDFLAGS) -o lb $(OBJS_RSD) $(LIBS)
- X
- Xlb.statsrv: $(OBJS_SRV)
- X $(CC) $(CFLAGS) $(LDFLAGS) -o lb $(OBJS_SRV)
- X
- Xtags:
- X ctags *.c > tags
- X
- Xclean:
- X rm -f core *.o
- X
- Xspotless:
- X rm -f core lb *.o
- X
- Xlove:
- X @echo 'not war?'
- X
- Xjoke:
- X @echo 'What do you want for nothing?'
- X
- Xshar:
- X @shar Makefile README INSTALL OTHER_SERVERS $(MANS) $(SRCS) >lb.shar
- X @chmod a+r lb.shar
- X @echo "SHAR file lb.shar created."
- X
- Xhardcopy:
- X lpr README INSTALL OTHER_SERVERS $(SRCS)
- X $(PRINT) $(MANS) | lpr -t
- X
- X# Dependencies
- Xlbmain.o: lbmain.c stats.h config.h
- Xst_sendrecv.o: st_sendrecv.c stats.h config.h
- Xrsdclnt.o: rsdclnt.c config.h
- END_OF_FILE
- if test 1069 -ne `wc -c <'Makefile'`; then
- echo shar: \"'Makefile'\" unpacked with wrong size!
- fi
- # end of 'Makefile'
- fi
- if test -f 'OTHER_SERVERS' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'OTHER_SERVERS'\"
- else
- echo shar: Extracting \"'OTHER_SERVERS'\" \(1224 characters\)
- sed "s/^X//" >'OTHER_SERVERS' <<'END_OF_FILE'
- X
- XWHAT? No rstatd? No statsrv? Fear not.
- X------------------------------------------
- X
- XLB is simple enough to modify for use with other servers. This package
- Xincludes client programs to talk to rstatd or statsrv, and these clients
- Xcan be used as templates for others.
- X
- Xstatsrv is available from comp.sources.unix archive servers.
- X
- X-------------------------------------------------------------------------
- XFrom the SunOS rstatd manual page:
- X
- X rstatd is a server which returns performance statistics obtained
- X from the kernel. The rstatd daemon is normally invoked by inetd(8C).
- X
- X-------------------------------------------------------------------------
- XThe opening paragraph from Dave Curry's statsrv README file:
- X
- X This is a remote statistics server as described in RFC996, "Statistics
- X Server", D. L. Mills, February 1987. With it, you can collect things
- X like load averages, number of users, uptime, and network statistics
- X from remote machines easily. (David Curry, davy@riacs.edu)
- X-------------------------------------------------------------------------
- X
- X ^Deke Kassabian, deke@ee.rochester.edu or ur-valhalla!deke
- X Univ of Rochester, Dept of EE, Rochester, NY 14627 (+1 716-275-3106)
- END_OF_FILE
- if test 1224 -ne `wc -c <'OTHER_SERVERS'`; then
- echo shar: \"'OTHER_SERVERS'\" unpacked with wrong size!
- fi
- # end of 'OTHER_SERVERS'
- fi
- if test -f 'README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'README'\"
- else
- echo shar: Extracting \"'README'\" \(2930 characters\)
- sed "s/^X//" >'README' <<'END_OF_FILE'
- X LB - The Load Balancer (version 1.2)
- X by Dikran Kassabian
- X
- X University Of Rochester
- X Department of Electrical Engineering
- X March 3, 1991
- X_______________________________________________________________________
- X
- XWhat is LB?
- X
- X LB is a load-balancing program. It can check the current
- X load on various machines on a LAN, and find the best candidate
- X machine to accept a new job to it's run queue. Additionally,
- X it can send the job to that machine using rsh(1).
- X
- X LB works best in homogeneous environments, where each machine
- X has similar or identical file system layout. Here at the
- X University of Rochester Department of Electrical Engineering,
- X we have nearly 70 SUN computers, which share home-directories
- X and local binaries. When a user sitting at a small workstation
- X wants to run a compute intensive job, LB helps to find a machine
- X on the network that has a low load, knowing that that machine
- X will also have his/her home directory and required program.
- X
- XHow to install LB:
- X
- X A separate file, called INSTALL, is included with detailed
- X installation notes, but briefly...
- X
- X To install lb, unpack the shar file (hmm, I guess you've already
- X done that :-), decide which statistics server you want to use
- X (rstatd or statsrv) and make the two small adjustments to the
- X Makefile, then type "make". The program 'lb' will be produced.
- X Then move 'lb' to an appropriate directory (/usr/local/bin),
- X edit and install the configuration file, and you're ready to
- X go. The relevant man pages are included, and can be installed
- X in your local man page directory.
- X
- XHow to use LB:
- X
- X To use lb, just type 'lb <command-line>' at your prompt, where
- X <command line> is some shell command you might normally type
- X at your prompt. LB will read a configuration file that tells
- X it about the candidate machines, select one, and then use rsh(1)
- X to run <command-line> on the specified machine.
- X
- X See the man page for lb(1) for more information.
- X
- XSpecial thanks to Dave Curry (davy@riacs.edu), whose statsrv server can
- Xbe used as an option to the rpc.rstatd server. He was nice enough to let
- Xme include some of his code with this package. The files st_sendrecv.c
- Xand stats.h are directly from his statsrv distribution.
- X
- XThis version of lb has been tested in only a few environments. It works on
- Xour Sun-3 and Sun-4 computers under SunOS 4.1. It also works on our 68030
- XNeXT Cubes under 1.0a OS. Previous versions ran on our Vax 11/750 under
- XMt.Xinu BSD (but that machine has since been retired). Beyond that I don't
- Xknow. If you port it to other operating systems and hardware, send me the
- Xdiffs so I can include them in the next release (if there is one).
- X
- XIf you have comments/fixes/bug-reports/flames, send 'em to me at
- Xdeke@ee.rochester.edu. I'll make every effort to reply, and to address
- Xyour concerns, but can't always guarantee that I can be quick about it.
- X
- XGood luck with lb! I hope you find it useful.
- END_OF_FILE
- if test 2930 -ne `wc -c <'README'`; then
- echo shar: \"'README'\" unpacked with wrong size!
- fi
- # end of 'README'
- fi
- if test -f 'config.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'config.h'\"
- else
- echo shar: Extracting \"'config.h'\" \(730 characters\)
- sed "s/^X//" >'config.h' <<'END_OF_FILE'
- X/* */
- X/* Configuration parameters for the load balancer, 'lb' */
- X/* Copyright (c) 1988, 1989 University of Rochester */
- X/* Department of Electrical Engineering. */
- X/* */
- X
- X#define CONFIGFILE "/usr/share/lb.conf"
- X#define RSH "/usr/ucb/rsh"
- X
- X#define loadavg(sp,n) (((float) (sp)->avenrun[n]) / 256.0)
- X#define MAXLINE 255 /* largest line in config file*/
- X#define MAXSHBUF 10240 /* max size of shell buffer */
- X#define MAXHOST 64 /* longest allowable hostname */
- X
- X#if u3b || u3b5 || sun
- X#define MAXFLOAT ((float)3.40282346638528860e+38)
- X#endif
- X
- X#if pdp11 || vax
- X#define MAXFLOAT ((float)1.701411733192644299e+38)
- X#endif
- X
- X#ifndef MAXFLOAT
- X#define MAXFLOAT ((float)1.701411733192644299e+38)
- X#endif
- END_OF_FILE
- if test 730 -ne `wc -c <'config.h'`; then
- echo shar: \"'config.h'\" unpacked with wrong size!
- fi
- # end of 'config.h'
- fi
- if test -f 'lb.1' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'lb.1'\"
- else
- echo shar: Extracting \"'lb.1'\" \(2521 characters\)
- sed "s/^X//" >'lb.1' <<'END_OF_FILE'
- X.tr ~ \
- X.TH LB 1 "options
- X.SH NAME
- XLb \- load balancer for homogeneous environment
- X.SH SYNOPSIS
- X.BR "lb [ -v | -q ] <command string>
- X.PP
- X.SH DESCRIPTION
- X.I lb
- Xfinds the best machine in the environment on which to run a batch type
- Xcompute task. This is done by comparing load averages
- Xand computing power for various machines, and selecting the machine
- Xbest able to accept the compute task.
- X.I lb
- Xis especially useful in distributing compute intensive jobs among
- Xthe many computers in a homogeneous environment.
- X.sp
- X.SH OPTIONS
- XWith no options,
- X.I lb
- Xprints a one line output identifying
- Xthe selected machine and the command being submitted.
- X.sp
- X.nf
- X -v verbose mode: causes an excessive amount of
- X information about the determination of the best
- X machine selection to be printed.
- X
- X -q quiet mode: causes even the usual one line
- X output identifying the selected machine to be
- X eliminated. The job will be sent to the remote
- X machine, but you will never be told which machine
- X was selected!
- X.fi
- X.SH EXAMPLES
- X.nf
- X.I lb
- X.fi
- X This gives the output of lb -v, but executes no command
- X.sp
- X.nf
- X.I lb fortune
- X.fi
- X This executes "fortune" on the least loaded machine.
- X.sp
- X.nf
- X.I lb -v foobar
- X.fi
- X This executes "foobar" on the least loaded machine, and gives
- Xverbose messages.
- X.sp
- X.nf
- X.I lb -q minimos infile
- X.fi
- X This executes "minimos infile" on the least loaded machine,
- Xand gives no messages.
- X.sp
- X.nf
- X.I lb 'spice<infile>outfile'
- X.fi
- X This is an important example. Here, a program called "spice" is
- Xbeing run with redirected input and output. Anytime redirection is
- Xdesired in using
- X.I lb,
- Xthe portion using redirection must be quoted to avoid interpretation at
- Xthe originating shell. The quoted string in this example allows for the
- Xredirection to take place on the remote machine.
- X.sp
- X.nf
- X.SH FILES
- X.fi
- X.I lb
- Xalso requires the configuration file
- X.I lb.conf
- Xwhich lists machines to be
- Xconsidered, and some basic information about them. See the manual
- Xpage lb(5) for more on the configuration file.
- X.nf
- X.SH CAVEATS
- X.fi
- X.sp
- X.I lb
- Xshould really use
- X.I csh job control
- Xso that the user may track the progress of the submitted job. Maybe in
- Xthe next version.
- X.sp
- X.nf
- X.SH NOTES
- XThis program is still under development. Send
- Xdescriptions of problems and/or comments to deke@ee.rochester.edu
- X(also ...!rochester!ur-valhalla!deke).
- X.SH AUTHOR
- X.nf
- XDikran Kassabian,
- XUniversity of Rochester Dept. of Electrical Engineering
- XRochester, NY 14627 (716) 275-3106
- X.SH "SEE ALSO"
- Xrstatd(8), statsrv(8), w(1), uptime(1), lb(5)
- END_OF_FILE
- if test 2521 -ne `wc -c <'lb.1'`; then
- echo shar: \"'lb.1'\" unpacked with wrong size!
- fi
- # end of 'lb.1'
- fi
- if test -f 'lb.5' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'lb.5'\"
- else
- echo shar: Extracting \"'lb.5'\" \(2063 characters\)
- sed "s/^X//" >'lb.5' <<'END_OF_FILE'
- X.tr ~ \
- X.TH LB 5 "limit
- X.SH NAME
- XLb.conf \- load balancer configuration file for lb(1)
- X.fi
- X.SH DESCRIPTION
- XThis file contains information about local machines recognized by
- X.IR lb (1).
- XThe format consists of single line entries with three fields. The
- Xfields are
- X.I machine-name,
- X.I power-factor,
- Xand
- X.I load-limit.
- X.sp
- X.I machine-name
- Xis a legal or recognized hostname which is to be a candidate for jobs
- Xinitiated through the use of lb(1). This machine must support the
- Xstatistics server protocol used by lb(1).
- X.sp
- X.I power-factor
- Xis a floating point value, and has meaning only by comparison to
- Xthe power-factors of other machines. The machines with the larger
- Xpower-factors will be preferred to those with smaller power-factors.
- X.sp
- X.I load-limit
- Xspecifies the load-average beyond which jobs should not be sent
- Xto that machine.
- X.sp
- X.SH SAMPLE FILE
- X.nf
- X# lb.conf
- X#
- X# The format of this file is <machine> <sfactor> <limit>
- X.ta .8i
- X# where <machine> is a legal machine name
- X# <sfactor> is that machines selection factor
- X# <limit> is the load limit for that machine
- X#
- X.ta 2.2i 3.2i
- X# MACHINE SFACTOR LIMIT
- Xbrahms.fubar.com 200 3.0
- Xmozart.fubar.com 150 2.5
- Xchopin.fubar.com 120 2.5
- Xbach.fubar.com 100 1.5
- X.sp
- X.fi
- XLines beginning with
- X.B #
- Xare comments.
- X.sp
- XIn this example, brahms.fubar.com is preferred to mozart.fubar.com, which
- Xis preferred to chopin.fubar.com, if their loads are exactly equal. In
- Xpractice, the load average (number of jobs in the run queue over the last
- Xminute) is compared to the load-limit and then divided by the power-factor,
- Xfor each machine listed. If the load average exceeds the load-limit, that
- Xmachine will not be considered. When all machines listed have been considered,
- Xthe one with the smallest value of (load-average/power-factor) will be
- Xselected.
- X.sp
- X.SH "SEE ALSO"
- Xlb(1), w(1), uptime(1)
- X.SH NOTES
- XThere are limits to the line-length and the hostname length, which are
- Xset in the file config.h when lb(1) is built. By default, these are
- X255 and 64 respectively, but may be tweaked at the installers discretion.
- END_OF_FILE
- if test 2063 -ne `wc -c <'lb.5'`; then
- echo shar: \"'lb.5'\" unpacked with wrong size!
- fi
- # end of 'lb.5'
- fi
- if test -f 'rsdclnt.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'rsdclnt.c'\"
- else
- echo shar: Extracting \"'rsdclnt.c'\" \(5598 characters\)
- sed "s/^X//" >'rsdclnt.c' <<'END_OF_FILE'
- X/*
- X * Copyright (c) 1989,1990,1991 University of Rochester
- X * Department of Electrical Engineering
- X * All rights reserved.
- X *
- X * Redistribution and use in source and binary forms are permitted
- X * provided that the above copyright notice and this paragraph are
- X * duplicated in all such forms and that any documentation,
- X * advertising materials, and other materials related to such
- X * distribution and use acknowledge that the software was developed
- X * at the University of Rochester.
- X *
- X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- X */
- X
- X/*
- X * rsdclnt.c for the 'lb' load balancer
- X * -Deke Kassabian, University of Rochester EE Department
- X * ( deke@ee.rochester.edu ) (716) 275-3106
- X *
- X * $Revision: 1.2 $
- X * $Author: deke $
- X * $Date: 91/03/03 17:52:36 $
- X * $Log: rsdclnt.c,v $
- X * Revision 1.2 91/03/03 17:52:36 deke
- X * changed stats to lstats to avoid name clash: required by change in rstat.h
- X *
- X */
- X
- X#include <stdio.h>
- X#include <rpc/rpc.h>
- X#include <rpcsvc/rstat.h>
- X#include "config.h"
- X
- Xmain(argc, argv, envp)
- Xint argc;
- Xchar *argv[];
- Xchar *envp[];
- X{
- X
- Xstruct statstime lstats;
- XFILE *fd,*fopen();
- Xchar *fgets();
- Xint getstats();
- X
- Xint start, /* where in the argv the command begins */
- X ppgrp, /* parent process group */
- X command, /* whether there is a command */
- X verbose_mode, /* all possible output */
- X quiet_mode; /* no output */
- X
- Xchar *path=RSH;
- X
- Xchar *dir,*pname;
- Xchar *cmd_exec[MAXSHBUF], /* command to execute (local) */
- X *rcmd_exec[MAXSHBUF], /* command to execute (remote) */
- X dbuf[MAXSHBUF], /* working directory placeholder */
- X host[MAXHOST], /* hostname placeholder */
- X best_host[MAXHOST], /* hostname placeholder */
- X fentry[MAXLINE]; /* file buffer */
- X
- Xfloat my_sfactor,
- X best_sfactor,
- X factor, limit, /* file variables */
- X load;
- X
- X pname = *argv; /* Name of this program */
- X verbose_mode=0,quiet_mode=0; /* Default is neither */
- X best_sfactor=MAXFLOAT; /* Practically infinity! */
- X command=1; /* There is a command */
- X
- X /* Check arguments.
- X *
- X * if argc=1 then verbose=Y and command=NULL
- X * if argc>=2 check for flags:
- X * -v=verbose (full output), -q=quiet (don't output machine selection)
- X * with no flags, only machine selection will be output
- X * The above flags are mutually exclusive. v overrides q
- X *
- X * Additional arguments are taken to be a command. No sanity checking
- X * will be done. When a machine is selected, the command will be sent
- X * to that machine as a shell command.
- X *
- X */
- X
- X if (argc == 1) {
- X command=0; /* no command to execute */
- X verbose_mode=1; /* verbose mode */
- X }
- X else {
- X start=1;
- X if(!strcmp(argv[1],"-q")){
- X quiet_mode=1; /* quiet mode - no output */
- X start=2;
- X if(argc == 2) exit(0); /* No command, no output! */
- X }
- X if(!strcmp(argv[1],"-v")){
- X verbose_mode=1; /* verbose mode */
- X start=2;
- X if(argc == 2) command=0; /* No command - verbose */
- X }
- X }
- X if(command){
- X for( ; start<argc ; start++){
- X strcat(cmd_exec," "); strcat(cmd_exec,argv[start]);
- X }
- X }
- X
- X
- X if((fd=fopen(CONFIGFILE,"r"))==0){
- X fprintf(stderr,"Error opening configuration file\n");
- X exit(1);
- X }
- X
- X while((fgets(fentry,MAXLINE,fd))!=NULL){
- X sscanf(fentry,"%s %f %f",host,&factor,&limit);
- X if(fentry[0]=='#') continue; /*ignore comments*/
- X
- X if(verbose_mode)
- X printf("\nHOST=%s\tFACTOR=%.2f\tLIMIT=%.2f\n",host,factor,limit);
- X
- X if(getstats(host,&lstats) !=0){
- X load=MAXFLOAT; /* skip this one */
- X }
- X else {
- X load=loadavg(&lstats,0);
- X }
- X
- X if( load > limit){
- X if(verbose_mode) printf("Host %s is over defined limit\n",host);
- X continue;
- X }
- X
- X my_sfactor=100*(load/factor);
- X
- X if(verbose_mode)
- X printf("Load avg=%.3f\tSelection factor=%.3f\n",
- X load,my_sfactor);
- X
- X if(best_sfactor>my_sfactor){
- X best_sfactor=my_sfactor;
- X strcpy(best_host,host);
- X }
- X } /*endwhile */
- X
- X if(verbose_mode)
- X printf("Selected host: <%s> factor=<%.3f>\n",best_host,best_sfactor);
- X
- X if(command){
- X sprintf(rcmd_exec,"(cd %s;%s)",getwd(dbuf),cmd_exec);
- X if(!quiet_mode){ /* print if not quiet_mode */
- X printf("\nrsh %s %s &\n",best_host,rcmd_exec);
- X }
- X ppgrp = getpgrp(getppid());
- X if (fork())
- X exit(0);
- X if(setpgrp(getpid(), ppgrp))
- X perror("stepgrp");
- X execle(path,path,best_host,rcmd_exec,(char *)0,envp); exit(0);
- X perror("");
- X }
- Xexit(0);
- X}
- X
- Xgetstats(hostname,lstats)
- Xchar *hostname;
- Xstruct statstime *lstats;
- X{
- Xint c;
- X c=rstat(hostname,lstats); /* rstat seems to return: */
- X /* 0 on success */
- X /* 13 on hostname lookup fail */
- X /* 14 on connection timeout */
- X /* 15 on "rstat not supported" */
- X /* I chose to generate my own error messages. perror() didn't */
- X /* give error messages I liked. Switch back to perror if you */
- X /* care to. */
- X
- X switch(c){
- X case 0:
- X break;
- X case 13:
- X fprintf(stderr,"rstat error (%d): ",c);
- X fprintf(stderr,"host %s is unknown.\n",hostname);
- X break;
- X case 14:
- X fprintf(stderr,"rstat error (%d): ",c);
- X fprintf(stderr,"host %s is down or unreachable.\n",hostname);
- X break;
- X case 15:
- X fprintf(stderr,"rstat error (%d): ",c);
- X fprintf(stderr,"host %s does not support protocol.\n",hostname);
- X break;
- X default:
- X fprintf(stderr,"rstat error (%d): ",c);
- X fprintf(stderr,"unknown error\n");
- X break;
- X }
- X return(c);
- X}
- END_OF_FILE
- if test 5598 -ne `wc -c <'rsdclnt.c'`; then
- echo shar: \"'rsdclnt.c'\" unpacked with wrong size!
- fi
- # end of 'rsdclnt.c'
- fi
- if test -f 'srvclnt.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'srvclnt.c'\"
- else
- echo shar: Extracting \"'srvclnt.c'\" \(5875 characters\)
- sed "s/^X//" >'srvclnt.c' <<'END_OF_FILE'
- X/*
- X * Copyright (c) 1989, University of Rochester
- X * Department of Electrical Engineering
- X * All rights reserved.
- X *
- X * Redistribution and use in source and binary forms are permitted
- X * provided that the above copyright notice and this paragraph are
- X * duplicated in all such forms and that any documentation,
- X * advertising materials, and other materials related to such
- X * distribution and use acknowledge that the software was developed
- X * at the University of Rochester.
- X *
- X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- X */
- X
- X/* srvclnt.c version 1.1 3/7/89
- X * for the 'lb' load balancer - by Deke Kassabian
- X *
- X * -Deke Kassabian, University of Rochester EE Department
- X * ( deke@ee.rochester.edu ) (716) 275-3106
- X */
- X
- X#include <sys/param.h>
- X#include <sys/socket.h>
- X#include <netinet/in.h>
- X#include <netdb.h>
- X#include <stdio.h>
- X#include <string.h>
- X#include "stats.h"
- X#include "config.h"
- X
- Xchar *pname;
- Xshort server = 0; /* indicates we aren't server */
- Xstruct sockaddr_in sin; /* address of remote host */
- X
- Xmain(argc, argv, envp)
- Xint argc;
- Xchar **argv;
- Xchar **envp;
- X{
- X FILE *fd,*fopen();
- X
- Xint start, /* where in the argv the command begins */
- X ppgrp, /* parent process group */
- X command, /* whether there is a command */
- X verbose_mode, /* all possible output */
- X quiet_mode; /* no output */
- X
- Xchar *path=RSH;
- X
- Xchar *dir;
- Xchar *cmd_exec[MAXSHBUF], /* command to execute (local) */
- X *rcmd_exec[MAXSHBUF], /* command to execute (remote) */
- X dbuf[MAXSHBUF], /* working directory placeholder */
- X host[MAXHOST], /* hostname placeholder */
- X best_host[MAXHOST], /* hostname placeholder */
- X fentry[MAXLINE]; /* file entry */
- X
- Xfloat my_sfactor,
- X best_sfactor,
- X load,
- X factor,limit; /* file variables */
- X
- X int socktype;
- X register int s;
- X char buf[10240];
- X struct hostent *hp;
- X struct servent *sp;
- X char *servtype;
- X struct hostent *gethostbyname();
- X struct servent *getservbyname();
- X
- X pname = *argv; /* Name of this program */
- X
- X verbose_mode=0,quiet_mode=0; /* Default is neither */
- X best_sfactor=MAXFLOAT; /* Practically infinity! */
- X command=1; /* There is a command */
- X
- X /* Check arguments.
- X *
- X * if argc=1 then verbose=Y and command=NULL
- X * if argc>=2 check for flags:
- X * -v=verbose (full output), -q=quiet (don't output machine selection)
- X * with no flags, only machine selection will be output
- X * The above flags are mutually exclusive. v overrides q
- X *
- X * Additional arguments are taken to be a command. No sanity checking
- X * will be done. When a machine is selected, the command will be run
- X * on that machine
- X *
- X */
- X
- X if (argc == 1) {
- X command=0; /* no command to execute */
- X verbose_mode=1; /* verbose mode */
- X }
- X else {
- X start=1;
- X if(!strcmp(argv[1],"-q")){
- X quiet_mode=1; /* quiet mode - no output */
- X start=2;
- X if(argc == 2) exit(0); /* No command, no output! */
- X }
- X if(!strcmp(argv[1],"-v")){
- X verbose_mode=1; /* verbose mode */
- X start=2;
- X if(argc == 2) command=0; /* No command - verbose */
- X }
- X }
- X
- X if(command){
- X for( ; start<argc; start++){
- X strcat(cmd_exec," "); strcat(cmd_exec,argv[start]);
- X }
- X }
- X
- X /* Open the config file */
- X if((fd=fopen(CONFIGFILE,"r"))==0){
- X fprintf(stderr,"Error opening configuration file ");
- X exit(1);
- X }
- X
- X /* Set up to use TCP stream sockets. */
- X servtype = "tcp";
- X socktype = SOCK_STREAM;
- X
- X /* Look up the port the server lives on. */
- X if ((sp = getservbyname(SERVNAME, servtype)) == NULL) {
- X fprintf(stderr, "%s: %s/%s: service unknown.\n",
- X pname, SERVNAME, servtype);
- X exit(1);
- X }
- X
- X /* Read the config file */
- X strcpy(best_host,"localhost");
- X while((fgets(fentry,MAXLINE,fd))!=NULL){
- X sscanf(fentry,"%s %f %f",host,&factor,&limit);
- X if(fentry[0]=='#') continue; /*ignore comments*/
- X
- X if(verbose_mode)
- X printf("\nHOST=%s\tFACTOR=%.2f\tLIMIT=%.2f\n",host,factor,limit);
- X
- X
- X /* Look up the host's address. */
- X if ((hp = gethostbyname(host)) == NULL) {
- X fprintf(stderr, "%s: %s: host unknown.\n", pname, host);
- X exit(1);
- X }
- X
- X /* Get a socket. */
- X if ((s = socket(AF_INET, socktype, 0)) < 0) {
- X error("socket");
- X exit(1);
- X }
- X
- X /* Build the server's address. */
- X sin.sin_port = sp->s_port;
- X sin.sin_family = hp->h_addrtype;
- X bcopy(hp->h_addr, &sin.sin_addr, sizeof(sin.sin_addr));
- X
- X /* connect to the remote host. */
- X if (connect(s, &sin, sizeof(struct sockaddr_in)) < 0) {
- X /* if not quiet mode, print connect error */
- X error("connect");
- X /* can't reach this host, try the next */
- X continue;
- X }
- X
- X /* make the request and grab the result */
- X st_send(s,"loadav");
- X st_recv(s,buf,sizeof(buf),"response");
- X sscanf(buf,"%f",&load);
- X
- X if( load > limit){
- X if(verbose_mode)
- X printf("Host %s is over defined limit\n",host);
- X continue;
- X }
- X
- X my_sfactor=100*( load / factor );
- X if(verbose_mode){
- X printf("Load avg=%.3f ",load);
- X printf("Selection factor=%.2f\n",my_sfactor);
- X }
- X
- X if(best_sfactor>my_sfactor){
- X best_sfactor=my_sfactor;
- X strcpy(best_host,host);
- X }
- X
- X } /*endwhile */
- X
- Xif(verbose_mode)
- X printf("Selected host: <%s> factor=<%.3f>\n",best_host,best_sfactor);
- X
- X if(command){
- X sprintf(rcmd_exec,"(cd %s;%s)",getwd(dbuf),cmd_exec);
- X if(!quiet_mode){ /* print if not quiet_mode */
- X printf("\nrsh %s %s &\n",best_host,rcmd_exec);
- X }
- X ppgrp = getpgrp(getppid());
- X if (fork())
- X exit(0);
- X if(setpgrp(getpid(), ppgrp))
- X perror("stepgrp");
- X execle(path,path,best_host,rcmd_exec,(char *)0,envp); exit(0);
- X perror("");
- X }
- Xexit(0);
- X}
- X
- Xerror(s)
- X{
- X fprintf(stderr, "%s: ", pname); perror(s);
- X}
- END_OF_FILE
- if test 5875 -ne `wc -c <'srvclnt.c'`; then
- echo shar: \"'srvclnt.c'\" unpacked with wrong size!
- fi
- # end of 'srvclnt.c'
- fi
- if test -f 'st_sendrecv.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'st_sendrecv.c'\"
- else
- echo shar: Extracting \"'st_sendrecv.c'\" \(1717 characters\)
- sed "s/^X//" >'st_sendrecv.c' <<'END_OF_FILE'
- X#ifndef lint
- Xstatic char *RCSid = "$Header: /ecn1/src/ecn/statsrv/RCS/st_sendrecv.c,v 1.2 87/10/19 08:37:02 davy Exp $";
- X#endif
- X/*
- X * st_sendrecv.c - stream send/recv functions
- X *
- X * David A. Curry
- X * Purdue University
- X * Engineering Computer Network
- X * davy@riacs.edu (previously davy@intrepid.ecn.purdue.edu)
- X * October, 1987
- X *
- X * $Log: st_sendrecv.c,v $
- X * Revision 1.2 87/10/19 08:37:02 davy
- X * Fixed to catch end of file on socket.
- X *
- X * Revision 1.1 87/10/17 21:01:46 davy
- X * Initial revision
- X *
- X */
- X#include <sys/param.h>
- X#include <sys/socket.h>
- X#include <netinet/in.h>
- X#include <syslog.h>
- X#include <stdio.h>
- X
- X#include "stats.h"
- X
- Xextern char *pname;
- Xextern short server;
- X
- X/*
- X * st_send - send buf on the socket s.
- X */
- Xst_send(s, buf)
- Xchar *buf;
- Xint s;
- X{
- X register int cnt;
- X
- X /*
- X * We want the length including the null.
- X */
- X cnt = strlen(buf) + 1;
- X
- X /*
- X * Send the buffer.
- X */
- X if (send(s, buf, cnt, 0) < 0) {
- X if (server)
- X syslog(LOG_ERR, "send: %m");
- X else
- X error("send");
- X exit(1);
- X }
- X}
- X
- X/*
- X * st_recv - receive data of maximum length cnt into the buffer buf on
- X * socket s. err describes what we're expecting for the error
- X * message.
- X */
- Xst_recv(s, buf, cnt, err)
- Xchar *buf, *err;
- Xint s, cnt;
- X{
- X char c;
- X register int n;
- X
- X /*
- X * Receive a character at a time up to a null.
- X */
- X do {
- X if ((n = recv(s, &c, sizeof(char), 0)) < 0) {
- X if (server)
- X syslog(LOG_ERR, "recv: %m");
- X else
- X error("recv");
- X exit(1);
- X }
- X
- X /*
- X * End of file.
- X */
- X if (n == 0)
- X exit(0);
- X
- X if (--cnt < 0) {
- X if (server)
- X syslog(LOG_ERR, "%s too long", err);
- X else
- X fprintf(stderr, "%s: %s too long.\n", pname, err);
- X exit(1);
- X }
- X
- X *buf++ = c;
- X } while (c != '\0');
- X}
- END_OF_FILE
- if test 1717 -ne `wc -c <'st_sendrecv.c'`; then
- echo shar: \"'st_sendrecv.c'\" unpacked with wrong size!
- fi
- # end of 'st_sendrecv.c'
- fi
- if test -f 'stats.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'stats.h'\"
- else
- echo shar: Extracting \"'stats.h'\" \(951 characters\)
- sed "s/^X//" >'stats.h' <<'END_OF_FILE'
- X/*
- X * $Header: /ecn1/src/ecn/statsrv/RCS/stats.h,v 1.2 87/12/17 14:54:27 davy Exp $
- X *
- X * stats.h - definitions for statistics server
- X *
- X * David A. Curry
- X * Purdue University
- X * Engineering Computer Network
- X * davy@intrepid.ecn.purdue.edu
- X * October, 1987
- X *
- X * $Log: stats.h,v $
- X * Revision 1.2 87/12/17 14:54:27 davy
- X * Added defines for VMUNIX and KMEM.
- X *
- X * Revision 1.1 87/10/17 21:01:03 davy
- X * Initial revision
- X *
- X */
- X
- X#define SERVNAME "statsrv" /* name of our service */
- X#define MAXDGRAM 576 /* maximum size of a datagram */
- X
- X#define KMEM "/dev/kmem" /* path to kernel memory */
- X
- X#if vax || sun || gould || tahoe
- X#define VMUNIX "/vmunix" /* path to kernel */
- X#endif
- X#if sequent
- X#define VMUNIX "/dynix"
- X#endif
- X
- X/*
- X * For 4.2BSD syslogs.
- X */
- X#ifndef LOG_DAEMON
- X#define LOG_DAEMON (3<<3)
- X#endif
- X
- Xextern int st_send(), st_recv(); /* stream send/recv functions */
- Xextern int dg_send(), dg_recv(); /* datagram send/recv functions */
- END_OF_FILE
- if test 951 -ne `wc -c <'stats.h'`; then
- echo shar: \"'stats.h'\" unpacked with wrong size!
- fi
- # end of 'stats.h'
- fi
- echo shar: End of archive.
- exit 0
- exit 0 # Just in case...
-